package com.hyxt.DTO.protocols;

import com.hyxt.utils.bytes.BytesUtil;
import io.netty.buffer.ByteBuf;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Map;

/**
 * @Description:终端上来的数据判断是天琴协议
 * @param :data：源数据
 * @return
 * @throws Exception
 */
public class TIANQCase extends CommonCase implements ICase {
    private static Log log = LogFactory.getLog(TIANQCase.class);
    /**
     * 天琴协议源数据上来的消息头
     */
    private byte fb = '*';
    /**
     * 天琴协议源数据上来的消息尾
     */
    private byte lb = '#';
    /**
     * 天琴协议源数据上来的消息头
     */
    private byte n = '$';
    /**
     * 天琴协议源数据上来的消息头
     */
    private byte y = 'Y';
    /**
     * 天琴协议源数据上来的消息头
     */
    private byte x = 'X';

    /**
     * @Description:判断协议类型
     * @param data
     * @return
     */
    @Override
    public boolean doCase(Object data) {
        byte[] bytes = (byte[]) data;
        // 第一个位
        byte firstFlag = BytesUtil.getByte(0, bytes);
        // 最后一位
        byte lastFlag = BytesUtil.getByte(bytes.length - 1, bytes);
        byte sign = BytesUtil.getByte(3, bytes);

        if (firstFlag == fb && lastFlag == lb && sign == ','&&bytes[bytes.length - 10] == ',') {// 正常源数据
            String body = new String(bytes);
            String[] splitBody = body.split(",");
            return true;
        }
        if (lastFlag == 00 && firstFlag == fb && bytes[bytes.length - 2] == 0x23 && sign == ','){
            return true;
        }
        // 正常源数据
        if (firstFlag == n && bytes.length % 32 == 0) {
            return true;
        }
        // 正常源数据
        if (firstFlag == x && bytes.length % 32 == 0) {
            return true;
        }
        if (firstFlag == y && bytes.length % 32 == 0) {
            return true;
        }
        return false;
    }

    @Override
    public byte getDataEnd() {
        return '#';
    }

    @Override
    public byte getDataHead() {
        return '*';
    }

    @Override
    public byte[] disassemblyByByteBuf(ByteBuf in) {
        byte[] message = new byte[in.readableBytes()];
        in.readBytes(message);
        log.info("TQCase:"+ BytesUtil.bytesToHexString(message));
        if (message[0] == '$' || message[0] == 'X' || message[0] == 'Y') {
            // 特殊变态协议
            return  special(message);
        } else if (message[0] == '*') {
            // 普通协议处理方法
             return normal(message);
        } else {
            for (int i = 0; i < message.length; i++) {
                if (message[i] == '*') {
                    byte[] newData = new byte[message.length - i];
                    System.arraycopy(message, i, newData, 0, newData.length);
                    return normal(newData);
                } else if (message[i] == '$' || message[i] == 'X' || message[i] == 'Y') {
                    byte[] newData = new byte[message.length - i];
                    System.arraycopy(message, i, newData, 0, newData.length);
                    return special(newData);
                }
            }
        }
        return null;
    }

    /**
     * 获取唯一标识
     * @param bytes
     * @return
     */
    @Override
    public String getSign(byte[] bytes){
            byte firstFlag = BytesUtil.getByte(0, bytes);
            // 最后一位
            byte lastFlag = BytesUtil.getByte(bytes.length - 1, bytes);
            byte sign = BytesUtil.getByte(3, bytes);
            if (firstFlag == fb && lastFlag == lb && sign == ',' && bytes[bytes.length - 10] == ',') {// 正常源数据
                String body = new String(bytes);
                String[] splitBody = body.split(",");
                return splitBody[1];
            } else {
                return BytesUtil.bcdToStr(BytesUtil.cutBytes(1, 5, bytes));
            }
        }

    public static void main(String[] args) {
        TIANQCase tianqCase = new TIANQCase();
       //byte[] bytes=BytesUtil.toStringHex("2481005118251351261206162718174600105182310e000329fffffbffff007f");
        byte[] bytes = "*HQ,3110105218,V4,S4,DF,FF,095143,015227,A,3958.5683,N,11619.2530,E,000.00,251,280714,FFFF7BFF#".getBytes();
        tianqCase.doCase(bytes);
    }

    /**
     * 特殊包拆解
     * @param receivedata
     * @return
     */
    private byte[] special (byte[] receivedata){
        if (receivedata.length >= 32) {
            for (int i = 0; i < receivedata.length;) {
                if ((receivedata[i] == '$' || receivedata[i] == 'X' || receivedata[i] == 'Y') && (receivedata.length - i) >= 32) {
                    byte[] datas = new byte[32];
                    System.arraycopy(receivedata, i, datas, 0, 32);
                    return datas;
                }
            }
        }
        return null;
    }

    /**
     * 正常包拆解
     * @param receivedata
     * @return
     */
    private byte[] normal(byte[] receivedata){
        int index = -1;
        // 因为数组第一位已经已知,所以for循环从1开始,b.length-2是因为只判断倒数后两位就可以了
        for (int i = 1; i <= receivedata.length - 1; i++) {
            // 找到7e7e相连位置，判断为数据尾
            if (receivedata[i] == getDataEnd()) {
                // 标识位index初始值设为-1，当前i的位置为数据尾所在位置，由于数组第一位从0开始，i-index为一个整包长度
                byte[] datas = new byte[i - index];
                // datas为一个整包
                System.arraycopy(receivedata, index + 1, datas, 0, i - index);
                return datas;
            }
        }
        return null;
    }

}
